#include "Aritmetico.cpp"
#include <assert.h>



bool hayUnderflow(char techo,char piso){
	if( ( techo == (techo | 0x80) ) and ( ~piso == (~piso | 0x80) ) ){
		if( ( ~techo == (~techo | 0x40) ) and ( piso == (piso | 0x40) ) ){
			return true;
		}
	}
	return false;
}

int resolverUnderflow(uChar techo,uChar piso){
	if( !hayUnderflow(techo,piso) ) return 0;
	uChar cont = 1;
	
	uChar nuevo_techo = 0x1;
	uChar nuevo_piso  = 0x0;
	
	
	// Cuento la cantidad de underflow 
	char mask = 0b00100000;
	char offset;
	for( offset = 3 ; offset<9 ; offset++ ){
		if( ( ~techo == (~techo | mask) ) and ( piso == (piso | mask) ) ){
			cont++;
		}else{
			break;
		}
		mask >>= 1;
	}

	cout << "offset: " << (int)offset << endl;
	cout << "Cantidad de overflow: " << (int)cont << endl;
	
	
	// Agrego, si los hay, los bits que no dieron 
	// underflow al nuevo techo y nuevo piso
	while( offset++ < 9 ){
		nuevo_techo <<= 1;
		if( techo == (techo | mask) ){
			nuevo_techo |= 0x01;
		}
		
		nuevo_piso <<= 1;
		if( piso == (piso | mask) ){
			nuevo_piso |= 0x01;
		}
		
		mask >>= 1;
	}
	
	// Agrego el padding para el techo (con bits en 1) y
	// para el piso (con bits en 0)
	while( cont-- > 0 ){
		
		nuevo_techo <<= 1;
		nuevo_techo |= 0x01;
		
		nuevo_piso <<= 1;
	}
	
	printf( "Nuevo techo hexa: %x \nNuevo piso hexa: %x\n" , nuevo_techo , nuevo_piso );

	return 0;
}


int resolverOverflow(uChar techo, uChar piso){

	uChar nuevoTecho = techo;
	uChar nuevoPiso  = piso;

	char aux = ~(techo ^ piso);

	char mask = 0x80;

	int cont = 0;

	for( uChar offset = 1 ; offset <= 8 ; offset++ ){
		if( aux == (aux | mask) ){
			if( techo == (techo | mask) ){
				cout << "Emito 1" << endl;
			}else{
				cout << "Emito 0" << endl;
			}
			cont++;
		}else{
			break;
		}
		
		mask >>= 1;
			
	}
	for( int aux = 0 ; aux < cont ; aux++ ){
		nuevoTecho <<= 1;
		nuevoTecho |= 0x01;
		
		nuevoPiso <<= 1;
	}
	
	printf("nuevoTecho: %x\n" , (uChar)nuevoTecho );
	printf("nuevoPiso: %x\n" , (uChar)nuevoPiso );

	return 0;
}

int test_comprimir_1(){
	// Comprime el bloque "ABAC" usando los caracteres A,B,C, completando a byte.
	
	AritmeticoCompress compress(false);
	
	compress.debug = true;
	
	vector<char> vectorChars;
	vectorChars.push_back('A');
	vectorChars.push_back('B');
	vectorChars.push_back('C');
	
	compress.setTablaChars( vectorChars );
	
	//compress.mostrarTabla();
	
	string salida("");
	string aux;
	
	compress.compressChar('A');
	compress.compressChar('B');
	
	compress.getSalidaComprimida(&aux);
	salida += aux;

	compress.compressChar('A');
	compress.compressChar('C',true);
	
	compress.getSalidaComprimida(&aux,true);
	salida += aux;
	
	string::iterator it;
	for ( it=salida.begin() ; it < salida.end(); it++ ){
		printf("HEXA: %x\n",(uChar)*it);
	}
	return 0;
}

int test_comprimir_2(){
	// Comprime el bloque "ABAC" usando todos los 256 caracteres.
	
	AritmeticoCompress compress(true);
	
	compress.debug = true;
	
	//compress.mostrarTabla();
	
	string salida("");
	string aux;
	
	compress.compressChar('A');
	compress.compressChar('B');
	
	compress.getSalidaComprimida(&aux);
	salida += aux;

	compress.compressChar('A');
	compress.compressChar('C',true);
	
	compress.getSalidaComprimida(&aux,true);
	salida += aux;
	
	string::iterator it;
	for ( it=salida.begin() ; it < salida.end(); it++ ){
		printf("HEXA: %x\n",(uChar)*it);
	}
	return 0;
}

int test_comprimir_3(){
	// Comprime el bloque "ABAC" usando solo los caracteres A,B,C, y completando a byte.
	
	AritmeticoCompress compress(false);
	
	compress.debug = true;
	
	vector<char> vectorChars;
	vectorChars.push_back('A');
	vectorChars.push_back('B');
	vectorChars.push_back('C');
	
	compress.setTablaChars( vectorChars );
	
	string salida;
	
	compress.runBlock( "ABAC" , &salida , true , true );
	
	string::iterator it;
	for ( it=salida.begin() ; it < salida.end(); it++ ){
		printf("HEXA: %x\n",(uChar)*it);
	}
	
	return 0;
}

int test_comprimir_4(){
	// Comprime el archivo input.txt, que contiene "ABAC eof", usando
	// solamente los caracteres A,B,C, y completando a byte.
	
	AritmeticoCompress compress("input.txt",4,false);
	
	compress.debug = true;
	
	vector<char> vectorChars;
	vectorChars.push_back('A');
	vectorChars.push_back('B');
	vectorChars.push_back('C');
	
	compress.setTablaChars( vectorChars );
	
	string aux("");
	string salida;
	
	compress.runNextBlock( &aux );
	
	salida += aux;
	
	compress.getSalidaComprimida(&aux,true);
	
	salida += aux;
	
	string::iterator it;
	for ( it=salida.begin() ; it < salida.end(); it++ ){
		printf("HEXA: %x\n",(uChar)*it);
	}
	
	return 0;
}

int test_comprimir_5(){
	// Comprime el archivo input.txt, que contiene "ABAC eof", usando
	// solamente los caracteres A,B,C.
	AritmeticoCompress compress("input.txt",4,false);
	
	compress.setOutputFilename("SalidaComprimidaAritmetico.dat");
	
	compress.debug = true;
	
	vector<char> vectorChars;
	vectorChars.push_back('A');
	vectorChars.push_back('B');
	vectorChars.push_back('C');
	
	compress.setTablaChars( vectorChars );
	
	compress.run();
	
	return 0;
}

int test_comprimir_6(){
	AritmeticoCompress compress(false);
	
	compress.debug = true;
	
	vector<char> vectorChars;
	vectorChars.push_back('D');
	vectorChars.push_back('I');
	vectorChars.push_back('O');
	vectorChars.push_back('S');
	vectorChars.push_back('V');
	
	compress.setTablaChars( vectorChars );
	
	//compress.mostrarTabla();
	
	string salida("");
	
	compress.compressChar('D');
	compress.compressChar('I');
	compress.compressChar('V');
	compress.compressChar('I');
	compress.compressChar('D');
	compress.compressChar('I');
	compress.compressChar('D');
	compress.compressChar('O');
	compress.compressChar('S',true);
	
	compress.getSalidaComprimida(&salida,true);
	
	string::iterator it;
	for ( it=salida.begin() ; it < salida.end(); it++ ){
		printf("HEXA: %x\n",(uChar)*it);
	}
	return 0;
}

int test_comprimir_7(){
	// Vamos a comprimir "0123 eof" usando 3 compresores, uno por cada nivel
	// del modelo estructurado
	
	string salidaN0("");
	string salidaN1("");
	string salidaN2("");
	
	string::iterator itN0;
	string::iterator itN1;
	string::iterator itN2;
	
	AritmeticoCompress compressN0(false);
	AritmeticoCompress compressN1(false);
	AritmeticoCompress compressN2(false);
	
	vector<char> vectorCharsN0;
	vector<char> vectorCharsN1;
	vector<char> vectorCharsN2;
	
	compressN0.debug = true;
	compressN1.debug = true;
	compressN2.debug = true;
	
	vectorCharsN0.push_back('1'); // escape
	vectorCharsN0.push_back('0');
	
	vectorCharsN1.push_back('0'); // escape
	vectorCharsN1.push_back('1');
	
	vectorCharsN2.push_back('0'); // escape
	vectorCharsN2.push_back('2');
	vectorCharsN2.push_back('3');
	
	compressN0.setTablaChars( vectorCharsN0 );
	compressN1.setTablaChars( vectorCharsN1 );
	compressN2.setTablaChars( vectorCharsN2 );
	
	compressN0.compressChar('0');
	compressN1.compressChar('1');
	compressN2.compressChar('2');
	compressN2.compressChar('3', true);
	
	compressN0.getSalidaComprimida(&salidaN0,false);
	compressN1.getSalidaComprimida(&salidaN1,false);
	compressN2.getSalidaComprimida(&salidaN2,true);
	
	for ( itN0=salidaN0.begin() ; itN0 < salidaN0.end(); itN0++ ){
		cout << "what the" << endl;
		printf("SALIDA NIVEL 0: %x\n",(uChar)*itN0);
	}
	for ( itN1=salidaN1.begin() ; itN1 < salidaN1.end(); itN1++ ){
		printf("SALIDA NIVEL 1: %x\n",(uChar)*itN1);
	}
	for ( itN2=salidaN2.begin() ; itN2 < salidaN2.end(); itN2++ ){
		printf("SALIDA NIVEL 2: %x\n",(uChar)*itN2);
	}
	return 0;
}

int test_comprimir_8(){
	AritmeticoCompress compress(false);
	
	compress.debug = true;
	
	vector<char> vectorChars;
	vectorChars.push_back('-');
	vectorChars.push_back('A');
	vectorChars.push_back('E');
	vectorChars.push_back('L');
	vectorChars.push_back('O');
	vectorChars.push_back('S');
	vectorChars.push_back('V');
	
	compress.setTablaChars( vectorChars );
	
	//compress.mostrarTabla();
	
	string salida("");
	
	compress.compressChar('S');
	compress.compressChar('O');
	compress.compressChar('L');
	compress.compressChar('-');
	compress.compressChar('S');
	compress.compressChar('E');
	compress.compressChar('-');
	compress.compressChar('V');
	compress.compressChar('A',true);
	
	
	compress.getSalidaComprimida(&salida,true);
	
	string::iterator it;
	for ( it=salida.begin() ; it < salida.end(); it++ ){
		printf("HEXA: %02X\n",(uChar)*it);
	}
	return 0;
}

int test_comprimir_9(){
	AritmeticoCompress compress(false);
	
	compress.debug = true;
	
	vector<char> vectorChars;
	vectorChars.push_back('!');
	vectorChars.push_back('"');
	vectorChars.push_back('#');
	vectorChars.push_back('$');
	vectorChars.push_back('%');
	vectorChars.push_back('&');
	vectorChars.push_back('/');
	vectorChars.push_back('(');
	vectorChars.push_back(')');
	vectorChars.push_back('=');

	
	compress.setTablaChars( vectorChars );
	
	compress.mostrarTabla();
	
	string salida("");
	
	compress.compressChar('=');
	compress.compressChar(')');
	compress.compressChar('(');
	compress.compressChar('/');
	compress.compressChar('&');
	compress.compressChar('%');
	compress.compressChar('$');
	compress.compressChar('#');
	compress.compressChar('"');
	compress.compressChar('!',true);

	
	
	compress.getSalidaComprimida(&salida,true);
	
	string::iterator it;
	for ( it=salida.begin() ; it < salida.end(); it++ ){
		printf("HEXA: %02X\n",(uChar)*it);
	}
	return 0;
}

int test_comprimir_10(){
	AritmeticoCompress compress(false);
	
	compress.debug = true;
	
	vector<char> vectorChars;
	vectorChars.push_back('A');
	vectorChars.push_back('B');
	vectorChars.push_back('C');
	vectorChars.push_back('D');
	vectorChars.push_back('E');
	vectorChars.push_back('F');
	vectorChars.push_back('G');
	vectorChars.push_back('H');
	vectorChars.push_back('I');
	vectorChars.push_back('J');

	
	compress.setTablaChars( vectorChars );
	
	compress.mostrarTabla();
	
	string salida("");
	

	compress.compressChar('G');
	compress.compressChar('H');
	compress.compressChar('I');
	compress.compressChar('J',true);

	
	
	compress.getSalidaComprimida(&salida,true);
	
	string::iterator it;
	for ( it=salida.begin() ; it < salida.end(); it++ ){
		printf("HEXA: %02X\n",(uChar)*it);
	}
	return 0;
}

int test_descomprimir_1(){
	AritmeticoDecompress decompress(false);
	
	decompress.debug = true;
	
	vector<char> vectorChars;
	vectorChars.push_back('D');
	vectorChars.push_back('I');
	vectorChars.push_back('O');
	vectorChars.push_back('S');
	vectorChars.push_back('V');
	
	decompress.setTablaChars(vectorChars);
	
	string comprimido("");
	string descomprimido("");
	comprimido += (char)0x0F;
	comprimido += (char)0xC0;
	comprimido += (char)0x40;
	
	decompress.decompressString(&comprimido,&descomprimido);
	
	return 0;
}

int test_descomprimir_2(){
	AritmeticoDecompress decompress(false);
	
	decompress.debug = true;
	
	vector<char> vectorChars;
	vectorChars.push_back('-');
	vectorChars.push_back('A');
	vectorChars.push_back('E');
	vectorChars.push_back('L');
	vectorChars.push_back('O');
	vectorChars.push_back('S');
	vectorChars.push_back('V');
	
	decompress.setTablaChars(vectorChars);
	
	string comprimido("");
	string descomprimido("");
	
	comprimido += (char)0xCA;
	comprimido += (char)0x09;
	comprimido += (char)0xA6;
	comprimido += (char)0xD3;
	comprimido += (char)0x80;
	
	
	decompress.decompressString(&comprimido,&descomprimido);
	
	return 0;
}

int test_descomprimir_3(){
	AritmeticoDecompress decompress(false);
	
	decompress.debug = true;
	
	vector<char> vectorChars;
	vectorChars.push_back('!');
	vectorChars.push_back('"');
	vectorChars.push_back('#');
	vectorChars.push_back('$');
	vectorChars.push_back('%');
	vectorChars.push_back('&');
	vectorChars.push_back('/');
	vectorChars.push_back('(');
	vectorChars.push_back(')');
	vectorChars.push_back('=');

	
	decompress.setTablaChars(vectorChars);
	
	string comprimido("");
	string descomprimido("");
	
	comprimido += (char)0xFA;
	comprimido += (char)0x59;
	comprimido += (char)0x7F;
	comprimido += (char)0xF9;
	comprimido += (char)0x40;
	comprimido += (char)0x40;
	
	decompress.decompressString(&comprimido,&descomprimido);
	
	return 0;
}

int test_descomprimir_4(){
	AritmeticoDecompress decompress(false);
	
	decompress.debug = true;
	
	vector<char> vectorChars;
	vectorChars.push_back('A');
	vectorChars.push_back('B');
	vectorChars.push_back('C');
	vectorChars.push_back('D');
	vectorChars.push_back('E');
	vectorChars.push_back('F');
	vectorChars.push_back('G');
	vectorChars.push_back('H');
	vectorChars.push_back('I');
	vectorChars.push_back('J');

	
	decompress.setTablaChars(vectorChars);
	
	string comprimido("");
	string descomprimido("");
	
	comprimido += (char)0xAE;
	comprimido += (char)0x03;
	comprimido += (char)0xC0;
	
	decompress.decompressString(&comprimido,&descomprimido);
	
	return 0;
}

int test_comprimir_y_descomprimir_1(){
	//AritmeticoCompress compress(true);
	//AritmeticoDecompress decompress(true);
	
	AritmeticoCompress compress(false);
	AritmeticoDecompress decompress(false);
	
	compress.debug = true;
	decompress.debug = true;
	
	vector<char> vectorChars;
	vectorChars.push_back('-');
	/*
	vectorChars.push_back('0');
	vectorChars.push_back('1');
	vectorChars.push_back('2');
	vectorChars.push_back('3');
	vectorChars.push_back('4');
	vectorChars.push_back('5');
	vectorChars.push_back('6');
	vectorChars.push_back('7');
	vectorChars.push_back('8');
	vectorChars.push_back('9');
	*/
	vectorChars.push_back('A');
	vectorChars.push_back('B');
	vectorChars.push_back('C');
	vectorChars.push_back('D');
	//vectorChars.push_back('E');
	//vectorChars.push_back('F');
	//vectorChars.push_back('G');
	//vectorChars.push_back('H');
	vectorChars.push_back('I');
	//vectorChars.push_back('J');
	//vectorChars.push_back('K');
	//vectorChars.push_back('L');
	//vectorChars.push_back('M');
	vectorChars.push_back('N');
	vectorChars.push_back('O');
	//vectorChars.push_back('P');
	//vectorChars.push_back('Q');
	//vectorChars.push_back('R');
	//vectorChars.push_back('S');
	//vectorChars.push_back('T');
	vectorChars.push_back('U');
	//vectorChars.push_back('V');
	//vectorChars.push_back('W');
	//vectorChars.push_back('X');
	//vectorChars.push_back('Y');
	//vectorChars.push_back('Z');

	compress.setTablaChars( vectorChars );
	decompress.setTablaChars( vectorChars );
	
	
	string comprimido("");
	string descomprimido("");
	
	compress.compressChar('B');
	compress.compressChar('O');
	compress.compressChar('C');
	compress.compressChar('A');
	compress.compressChar('-');
	compress.compressChar('U');
	compress.compressChar('N');
	compress.compressChar('I');
	compress.compressChar('D');
	compress.compressChar('O',true);

	compress.getSalidaComprimida(&comprimido,true);
	
	decompress.decompressString(&comprimido,&descomprimido);
	
	/*
	string::iterator it;
	for ( it=comprimido.begin() ; it < comprimido.end(); it++ ){
		printf("HEXA: %02X\n",(uChar)*it);
	}
	*/
	
	return 0;
}

int test_comprimir_y_descomprimir_2(){
	//AritmeticoCompress compress(true);
	//AritmeticoDecompress decompress(true);
	
	AritmeticoCompress nivel1comp(false);
	AritmeticoDecompress nivel1decomp(false);
	AritmeticoCompress nivel2comp(false);
	AritmeticoDecompress nivel2decomp(false);
	AritmeticoCompress nivel3comp(false);
	AritmeticoDecompress nivel3decomp(false);
	
	nivel1comp.debug = true;
	nivel1decomp.debug = true;
	nivel2comp.debug = true;
	nivel2decomp.debug = true;
	nivel3comp.debug = true;
	nivel3decomp.debug = true;
	
	vector<char> vectorCharsN1;
	//vectorCharsN1.push_back('0'); // 0
	//vectorCharsN1.push_back('E'); // ESC
	vectorCharsN1.push_back(0x00); // 0
	vectorCharsN1.push_back(0x01); // ESC
	vector<char> vectorCharsN2;
	//vectorCharsN2.push_back('1'); // 1
	//vectorCharsN2.push_back('E'); // ESC
	vectorCharsN2.push_back(0x01); // 1
	vectorCharsN2.push_back(0x00); // ESC
	vector<char> vectorCharsN3;
	//vectorCharsN3.push_back('2'); // 2
	//vectorCharsN3.push_back('3'); // 3
	//vectorCharsN3.push_back('E'); // ESC
	vectorCharsN3.push_back(0x02); // 2
	vectorCharsN3.push_back(0x03); // 3
	vectorCharsN3.push_back(0x00); // ESC

	nivel1comp.setTablaChars( vectorCharsN1 );
	nivel1decomp.setTablaChars( vectorCharsN1 );
	nivel2comp.setTablaChars( vectorCharsN2 );
	nivel2decomp.setTablaChars( vectorCharsN2 );
	nivel3comp.setTablaChars( vectorCharsN3 );
	nivel3decomp.setTablaChars( vectorCharsN3 );
	
	
	string comprimidoN1("");
	string comprimidoN2("");
	string comprimidoN3("");
	string descomprimidoN1("");
	string descomprimidoN2("");
	string descomprimidoN3("");
	
	// 0123
	//nivel1comp.compressChar('0');
	//nivel1comp.compressChar('E');
	//nivel1comp.compressChar('E');
	//nivel1comp.compressChar('E',true);
	nivel1comp.compressChar(0x00);
	nivel1comp.compressChar(0x01);
	nivel1comp.compressChar(0x01);
	nivel1comp.compressChar(0x01,true);
	
	// 0123
	//nivel2comp.compressChar('1');
	//nivel2comp.compressChar('E');
	//nivel2comp.compressChar('E',true);
	nivel2comp.compressChar(0x01);
	nivel2comp.compressChar(0x00);
	nivel2comp.compressChar(0x00,true);
	
	// 0123
	//nivel3comp.compressChar('2');
	//nivel3comp.compressChar('3',true);
	nivel3comp.compressChar(0x02);
	nivel3comp.compressChar(0x03,true);

	nivel1comp.getSalidaComprimida(&comprimidoN1,true);
	nivel2comp.getSalidaComprimida(&comprimidoN2,true);
	nivel3comp.getSalidaComprimida(&comprimidoN3,true);
	
	nivel1decomp.decompressString(&comprimidoN1,&descomprimidoN1);
	nivel2decomp.decompressString(&comprimidoN2,&descomprimidoN2);
	nivel3decomp.decompressString(&comprimidoN3,&descomprimidoN3);
	
	cout << endl << endl;
	cout << "Nivel 1: " << descomprimidoN1 << endl;
	cout << "Nivel 2: " << descomprimidoN2 << endl;
	cout << "Nivel 3: " << descomprimidoN3 << endl;
	/*
	string::iterator it;
	for ( it=comprimido.begin() ; it < comprimido.end(); it++ ){
		printf("HEXA: %02X\n",(uChar)*it);
	}
	*/
	
	return 0;
}

int test_comprimir_archivo(){
	ifstream  inputFile("input.txt", ios::binary);
	ofstream outputFile("Aritmetico.comprimido.dat", ios::binary);
	
	AritmeticoCompress compress(true);
	//AritmeticoCompress compress(false);
	
	/*
	vector<char> vectorChars;
	vectorChars.push_back('-');
	vectorChars.push_back('0');
	vectorChars.push_back('1');
	vectorChars.push_back('2');
	vectorChars.push_back('3');
	vectorChars.push_back('4');
	vectorChars.push_back('5');
	vectorChars.push_back('6');
	vectorChars.push_back('7');
	vectorChars.push_back('8');
	vectorChars.push_back('9');
	
	compress.setTablaChars( vectorChars );
	*/
	
	char charActual;
	char nextChar;
	string leido;
	
	charActual = inputFile.get();
	while(inputFile.good()){
		nextChar = inputFile.get();
		if( charActual > 0 ){
			compress.compressChar(charActual);
			leido += charActual;
		}
		charActual = nextChar;
	}
	if( charActual > 0 ){
		compress.compressChar(charActual,true);
		leido += charActual;
	}
	
	string comprimido;
	compress.getSalidaComprimida(&comprimido,true);
	
	cout << "Leido: '" << leido << "'" << endl;
	
	outputFile << comprimido;
	
	inputFile.close();
	outputFile.close();
	return 0;
}

int test_descomprimir_archivo(){
	ifstream  inputFile("Aritmetico.comprimido.dat", ios::binary);
	ofstream outputFile("Aritmetico.descomprimido.txt", ios::binary);
	
	AritmeticoDecompress decompress(true);
	//AritmeticoDecompress decompress(false);
	
	/*
	vector<char> vectorChars;
	vectorChars.push_back('-');
	vectorChars.push_back('0');
	vectorChars.push_back('1');
	vectorChars.push_back('2');
	vectorChars.push_back('3');
	vectorChars.push_back('4');
	vectorChars.push_back('5');
	vectorChars.push_back('6');
	vectorChars.push_back('7');
	vectorChars.push_back('8');
	vectorChars.push_back('9');
	
	decompress.setTablaChars( vectorChars );
	*/
	
	// Leo un bloque
	int blockSize = 900*1024;
	char* bufferLectura = new char[blockSize];
	inputFile.read(bufferLectura,blockSize);
	
	// Cambio el tipo de dato, de char* a string
	string dataComprimida, salidaDescomprimida;
	dataComprimida.assign(bufferLectura,0,inputFile.gcount());
	delete[] bufferLectura;
	
	decompress.decompressString( &dataComprimida , &salidaDescomprimida );
	
	outputFile << salidaDescomprimida;
	
	inputFile.close();
	outputFile.close();
	return 0;
}

int main(){
	
	//test_comprimir_1();
	//test_comprimir_2();
	//test_comprimir_3();
	//test_comprimir_4();
	//test_comprimir_5();
	//test_comprimir_6();
	//test_comprimir_7();
	//test_comprimir_8();
	//test_comprimir_9();
	//test_comprimir_10();
	
	//test_descomprimir_1();
	//test_descomprimir_2();
	//test_descomprimir_3();
	//test_descomprimir_4();
	
	//test_comprimir_y_descomprimir_1();
	//test_comprimir_y_descomprimir_2();
	
	test_comprimir_archivo();
	test_descomprimir_archivo();
	
	/*
	compress.actualizarTblFrecuencias(a);
	compress.actualizarTblFrecuencias(b);
	compress.actualizarTblFrecuencias(c);
	compress.actualizarTblFrecuencias(a);
	compress.mostrarTabla();
	
	uChar techo = 255;
	uChar piso  = 0;
	
	unsigned short rango = techo - piso + 1;
	
	printf( "%f\n" , compress.calcularTecho(b) );
	printf( "%f\n" , compress.calcularPiso(b) );
	
	uChar nuevoTecho = (uChar)(piso - 1 + (rango*compress.calcularTecho(b)) );
	uChar nuevoPiso  = (uChar)(piso     + (rango*compress.calcularPiso(b) ) );
	
	printf( "NT: %d\n" , nuevoTecho );
	printf( "NP: %d\n" , nuevoPiso );
	*/
	
	return 0;
}
